package com.gim.util;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class NettyServer implements CommandLineRunner, DisposableBean {

    private final Logger logger = LoggerFactory.getLogger(NettyServer.class);

    private Channel serverChannel;
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    @Autowired
    private MyChannelHandler myChannelHandler; // 注入 handler

    @Value("${netty.port}")
    private int port;

    @Value("${netty.host}")
    private String host;

    @Override
    public void run(String... args) {
        try {
            Bootstrap bootstrap = new Bootstrap();

            bootstrap.group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline()
                                    .addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4))
                                    .addLast(new LengthFieldPrepender(4))
                                    .addLast(myChannelHandler); // 添加 Spring 管理的 handler
                        }
                    });

            serverChannel = bootstrap.connect(host, port).sync().channel();
            logger.debug("Netty server started on {}:{}", host, port);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("Netty server failed to start", e);
            throw new RuntimeException("Netty server failed to start", e);
        }
    }

    @Override
    public void destroy() {
        if (serverChannel != null) {
            serverChannel.close();
        }
        workerGroup.shutdownGracefully();
    }
}